// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: duration.cpp 225 2008-09-12 17:43:02Z heavyzheng $
//

#ifndef ZZHENG_QUANT_DATES_SOURCE
#define ZZHENG_QUANT_DATES_SOURCE
#endif // ZZHENG_QUANT_DATES_SOURCE

#include <zzheng/quant/dates/duration.hpp>

#ifdef ZZHENG_MSVC
#  pragma warning(push)
#  pragma warning(disable: 4127 4511 4512)
#endif // ZZHENG_MSVC

#include <boost/lexical_cast.hpp>

#ifdef ZZHENG_MSVC
#  pragma warning(pop)
#endif // ZZHENG_MSVC

#include <cassert>
#include <string>

namespace zzheng {
namespace quant {
namespace dates {

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // constructors
    //

    duration::duration(): count_(0), unit_(month) {
        // Do nothing.
    }

    duration::duration(count_type count, unit_type unit): count_(count), unit_(unit) {
        // Do nothing.
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // operators
    //

    bool duration::operator==(const duration& rhs) const {
        return (daycount() == rhs.daycount());
    }

    bool duration::operator<(const duration& rhs) const {
        return (daycount() < rhs.daycount());
    }

    bool duration::operator!=(const duration& rhs) const {
        return !operator==(rhs);
    }

    bool duration::operator>(const duration& rhs) const {
        return (!operator==(rhs) && !operator<(rhs));
    }

    bool duration::operator<=(const duration& rhs) const {
        return (operator==(rhs) || operator<(rhs));
    }

    bool duration::operator>=(const duration& rhs) const {
        return !operator<(rhs);
    }

    duration duration::operator-() const {
        return duration(-count_, unit_);
    }

    duration duration::operator*(int multiplier) const {
        return duration(count_ * multiplier, unit_);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // public member functions
    //

    void duration::swap(duration& rhs) {
        duration tmp(*this);
        *this = rhs;
        rhs = tmp;
    }

    bool duration::empty() const {
        return (daycount() == 0);
    }

    duration::count_type duration::count() const {
        return count_;
    }

    duration::unit_type duration::unit() const {
        return unit_;
    }

    duration::count_type duration::daycount() const {
        return (count_ * unit_);
    }

    std::string duration::str() const {
        std::string unit_str;
        switch (unit_) {
        case day:
            unit_str = "D";
            break;
        case week:
            unit_str = "W";
            break;
        case month:
            unit_str = "M";
            break;
        case year:
            unit_str = "Y";
            break;
        default:
            assert(! "Invalid duration unit: programming error.");
            unit_str = "M";
            break;
        }
        return ( boost::lexical_cast<std::string>(count_) + unit_str );
    }

} // namespace zzheng::quant::dates
} // namespace zzheng::quant
} // namespace zzheng




